package com.emm.yixun.website.service.ao.DataService;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.emm.yixun.common.model.*;
import com.emm.yixun.common.model.dto.*;
import com.emm.yixun.common.model.enums.*;
import com.emm.yixun.common.response.Response;
import com.emm.yixun.common.response.ResponseList;
import com.emm.yixun.common.utils.DateStyle;
import com.emm.yixun.common.utils.DateUtils;
import com.emm.yixun.common.utils.HttpUtil;
import com.emm.yixun.customer.service.*;
import com.emm.yixun.estate.service.ProjectRoomServiceFacade;
import com.emm.yixun.marketing.service.BusinessAbnormaServiceFacade;
import com.emm.yixun.marketing.service.HaveReceiveRefundServiceFacade;
import com.emm.yixun.marketing.service.NeedReceiveRefundServiceFacade;
import com.emm.yixun.system.service.BaseCodeValueServiceFacade;
import com.emm.yixun.system.service.ImageServiceFacade;
import com.emm.yixun.system.service.UserServiceFacade;
import com.emm.yixun.website.common.ajax.AjaxRes;
import com.emm.yixun.website.constant.EhcacheConstant;
import com.emm.yixun.website.constant.PmoConfig;
import com.emm.yixun.website.service.ActivitiProcessServiceImpl;
import com.emm.yixun.website.service.CacheUtils;
import com.emm.yixun.website.service.marketing.HaveReceiveRefundService;
import com.emm.yixun.website.service.process.ProcessService;
import com.emm.yixun.website.vo.changeroom.SignedChangeVo;
import com.emm.yixun.website.vo.oaExcel.BridgeResult;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

@Service("oaDataService")
public class OaDataServiceImp implements OaDataService {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private PmoConfig pmoConfig;

	@Autowired
	private ProjectRoomServiceFacade projectRoomServiceFacade;

	@Autowired
	private CustomerServiceFacade customerServiceFacade;

	@Autowired
	private BaseCodeValueServiceFacade baseCodeValueServiceFacade;

	@Autowired
	private FamilyMemberServiceFacade familyMemberServiceFacade;

	@Autowired
	private SubscribeServiceFacade subscribeServiceFacade;

	@Autowired
	private SignedServiceFacade signedServiceFacade;

	@Autowired
	private ImageServiceFacade imageServiceFacade;

	@Autowired
	private UserServiceFacade userServiceFacade;
	@Autowired
	private BusinessAbnormaServiceFacade businessAbnormaServiceFacade;
	@Autowired
	private HaveReceiveRefundService haveReceiveRefundService;
	@Autowired
	private NeedReceiveRefundServiceFacade needReceiveRefundServiceFacade;
	@Autowired
	private HaveReceiveRefundServiceFacade haveReceiveRefundServiceFacade;

	@Autowired
	private TaskService taskService;

	@Autowired
	private RuntimeService runtimeService;

	@Autowired
	private ActivitiProcessServiceImpl activitiProcessServiceImpl;

	@Autowired
	private IdentityService identityService;

	@Autowired
	private OaSendHttpMessageService oaSendHttpMessageService;

	@Autowired
	private SendMessageServiceFacade sendMessageServiceFacade;

	@Autowired
	private ProcessService processService;

	@Autowired
	private CacheUtils cacheUtils;

	/**
	 * @Title: getEstateRecord @Description: 组装房源信息 @param @param
	 *         roomId @param @return 设定文件 @return JSONObject 返回类型 @throws
	 */
	@Override
	public JSONObject getEstateRecord(Long roomId) {
		JSONObject projectRoomJson = new JSONObject();
		Response<ProjectRoom> response = projectRoomServiceFacade.findById(roomId);
		if (response.isSuccess()) {
			ProjectRoom projectRoom = response.getEntity();
			projectRoomJson.put("combinedName", projectRoom.getCombinedName()); // 房号
			projectRoomJson.put("buildingArea", projectRoom.getBuildingArea());
			projectRoomJson.put("sharingArea", projectRoom.getSharingArea());
			projectRoomJson.put("innerArea", projectRoom.getInnerArea());
			projectRoomJson.put("billingArea", projectRoom.getBillingArea());
			projectRoomJson.put("roomStatusName",
					StringUtils.isNotBlank(projectRoom.getRoomStatus())
							? RoomStatusEnum.getByNo(projectRoom.getRoomStatus()).getDes()
							: "");
		}
		return projectRoomJson;
	}

	/**
	 *
	 * @Title: getCustomerRecord @Description: 组装客户信息 @param @param
	 *         customerId @param @return 设定文件 @return JSONObject 返回类型 @throws
	 */
	public JSONObject getCustomerRecord(Long customerId) {
		JSONObject customerJson = new JSONObject();
		Response<Customer> response = customerServiceFacade.findById(customerId);
		if (response.isSuccess()) {
			Customer customer = response.getEntity();
			customerJson.put("customerName", customer.getCustomerName());
			BaseCodeValueDto bcvDto = new BaseCodeValueDto();
			bcvDto.setMerchantId(customer.getMerchantId());
			ResponseList<BaseCodeValue> bcvResList = baseCodeValueServiceFacade.selectListFilterDelFlag(bcvDto);
			Map<Long, String> bcvMap = new HashMap<Long, String>();
			if (bcvResList.isSuccess()) {
				List<BaseCodeValue> bcvList = bcvResList.getEntity();
				for (BaseCodeValue bcv : bcvList) {
					bcvMap.put(bcv.getId(), bcv.getCodeName());
				}
			}
			if (StringUtils.isNotBlank(customer.getPeDocumentType())) {
				customerJson.put("peDocumentTypeName", bcvMap.get(Long.parseLong(customer.getPeDocumentType())));
			}
			customerJson.put("peDocumentNumber", customer.getPeDocumentNumber());
			customerJson.put("customerPhone", customer.getCustomerPhone());
			customerJson.put("peContactAddress", customer.getPeContactAddress());
			customerJson.put("pePostcode", customer.getPePostcode());
			if (StringUtils.isNotBlank(customer.getCustomerOrigin())) {
				customerJson.put("customerOriginName", bcvMap.get(Long.parseLong(customer.getCustomerOrigin())));
			}
		}
		return customerJson;
	}

	/**
	 * <p>
	 * Title: getFamilyMember
	 * </p>
	 * <p>
	 * Description:共同购房者
	 * </p>
	 * 
	 * @param dto
	 * @return
	 * @see com.emm.yixun.website.service.ao.DataService.OaDataService#getFamilyMember(com.emm.yixun.common.model.dto.FamilyMemberDto)
	 */
	@Override
	public List<FamilyMember> getFamilyMember(FamilyMemberDto dto) {
		ResponseList<FamilyMember> responseList = familyMemberServiceFacade.findByDto(dto);
		if (responseList.isSuccess() && responseList.getEntity() != null) {
			for (FamilyMember member : responseList.getEntity()) {
				if (!StringUtils.isEmpty(member.getDocumentType())) {
					Response<BaseCodeValue> baseCodeValue = baseCodeValueServiceFacade
							.findById(new Long(member.getDocumentType()));
					if (baseCodeValue.isSuccess() && baseCodeValue.getEntity() != null) {
						member.setDocumentType(baseCodeValue.getEntity().getCodeName());
					}
				}

			}
			return responseList.getEntity();
		}
		return null;
	}

	/**
	 * <p>
	 * Title: getsubscribeRecord
	 * </p>
	 * <p>
	 * Description:认购信息
	 * </p>
	 * 
	 * @param id
	 * @return
	 * @see com.emm.yixun.website.service.ao.DataService.OaDataService#getsubscribeRecord(java.lang.Long)
	 */
	@Override
	public JSONObject getsubscribeRecord(Long id) {
		SubscribeInfo subscribe = subscribeServiceFacade.findByIdInfo(id).getEntity();
		String subscribeStr = JSON.toJSONString(subscribe);
		HashMap<String, Double> maps = signedServiceFacade.signedContractAmount(null, id);
		Double payAepositAmount = 0d;
		Double subscribeAmount = 0d;
		if (null != maps.get("payAepositAmount")) {
			payAepositAmount = maps.get("payAepositAmount");
		}
		if (null != maps.get("subscribeAmount")) {
			subscribeAmount = maps.get("subscribeAmount") - payAepositAmount;
		}
		JSONObject object = JSONObject.parseObject(subscribeStr);
		object.put("alsubscribeAmount", subscribeAmount);
		object.put("userName", subscribe.getUserName());

		return object;
	}

	/**
	 * <p>
	 * Title: 查询流程附件
	 * </p>
	 * <p>
	 * Description:
	 * </p>
	 * 
	 * @param objectId
	 * @param imageType
	 * @return
	 * @see com.emm.yixun.website.service.ao.DataService.OaDataService#queryProcessImages(java.lang.String,
	 *      java.lang.String)
	 */
	@Override
	public List<Image> queryProcessImages(String objectId, String imageType, Long merchantId) {
		ImageDto imageDto = new ImageDto();
		imageDto.setObjectId(Long.parseLong(objectId));
		imageDto.setImgType(imageType);
		imageDto.setMerchantId(merchantId);
		ResponseList<Image> resImageList = imageServiceFacade.findByDto(imageDto);
		if (resImageList.isSuccess() && resImageList.getEntity() != null) {
			return resImageList.getEntity();
		}
		return null;
	}

	/**
	 * 认购换房信息
	 * 
	 * @param subscribeId
	 *            认购Id
	 * @param businessAbnormaId
	 *            销控异常业务Id
	 * @return
	 */
	@Override
	public JSONObject loadSubChangeNameInfo(Long subscribeId, String businessAbnormaId) {
		JSONObject data = new JSONObject();

		Response<SubscribeInfo> subscribeInfoResponse = subscribeServiceFacade.findByIdInfo(subscribeId);
		if (subscribeInfoResponse.isSuccess() && null != subscribeInfoResponse.getEntity()) {
			SubscribeInfo subscribeInfo = subscribeInfoResponse.getEntity();
			String subscribeStr = JSON.toJSONString(subscribeInfo);
			data = JSONObject.parseObject(subscribeStr);
			// 客户名称
			data.put("customerName", "");
			Response<Customer> customerResponse = customerServiceFacade.findById(subscribeInfo.getCustomerId());
			if (customerResponse.isSuccess() && null != customerResponse.getEntity()) {
				data.put("customerName", customerResponse.getEntity().getCustomerName());
			}

			// 房号
			data.put("roomName", "");
			Response<ProjectRoom> projectRoomResponse = projectRoomServiceFacade.findById(subscribeInfo.getRoomId());
			if (projectRoomResponse.isSuccess() && null != projectRoomResponse.getEntity()) {
				data.put("roomName", projectRoomResponse.getEntity().getCombinedName());
			}
			data.put("agentName", "");
			Response<User> userResponse = userServiceFacade.findById(subscribeInfo.getAgentId());
			if (userResponse.isSuccess() && null != userResponse.getEntity()) {
				data.put("agentName", userResponse.getEntity().getUserName());
			}

			data.put("remark", "");
			data.put("tcCreateTime", "");
			if (StringUtils.isNotBlank(businessAbnormaId)) {
				Response<BusinessAbnorma> businessAbnormaResponse = businessAbnormaServiceFacade
						.findById(Long.valueOf(businessAbnormaId));
				if (businessAbnormaResponse.isSuccess() && null != businessAbnormaResponse.getEntity()) {
					data.put("remark", businessAbnormaResponse.getEntity().getRemark());
					data.put("tcCreateTime", DateUtils.DateToString(businessAbnormaResponse.getEntity().getCreateTime(),
							DateStyle.YYYY_MM_DD.getValue()));
				}
			}
		}
		return data;
	}

	/**
	 * 签约换房信息
	 * 
	 * @param signedId
	 *            签约Id
	 * @param businessAbnormaId
	 *            销控异常业务Id
	 * @return
	 */
	@Override
	public JSONObject loadSignedChangeNameInfo(Long signedId, String businessAbnormaId) {
		JSONObject data = new JSONObject();
		Response<SignedInfo> signedResponse = signedServiceFacade.findByIdInfo(signedId);
		if (signedResponse.isSuccess() && null != signedResponse.getEntity()) {
			Signed signed = signedResponse.getEntity();
			String subscribeStr = JSON.toJSONString(signed);
			data = JSONObject.parseObject(subscribeStr);
			// 客户名称
			Response<Customer> customerResponse = customerServiceFacade.findById(signed.getCustomerId());
			if (customerResponse.isSuccess() && null != customerResponse.getEntity()) {
				data.put("customerName", customerResponse.getEntity().getCustomerName());
			} else {
				data.put("customerName", "");
			}
			HaveReceiveRefundDto hrrDto = new HaveReceiveRefundDto();
			hrrDto.setRelationId(signed.getId());
			hrrDto.setDocType(DocTypeEnum.COLLECTION.getNo());
			hrrDto.setReceivablesType(ReceivablesTypeEnum.SIGNED.getNo());
			hrrDto.setTransferStatus("0");
			double haveCollection = haveReceiveRefundService.getRealAmount(hrrDto);
			// 已收房款
			data.put("haveCollection", haveCollection);

			BigDecimal liquidat = BigDecimal.ZERO;
			if (signed.getLiquidat() == null) {
				signed.setLiquidat(BigDecimal.ZERO);
			}
			if (new BigDecimal(haveCollection).compareTo(signed.getLiquidat()) > 0) {
				data.put("sigLiquidat", new BigDecimal(haveCollection).subtract(signed.getLiquidat()));
			} else {
				data.put("sigLiquidat", liquidat);
			}
			// 已收定金
			data.put("subscribeAmount", getSubscribeAmount(signed.getPayDepositId(), signed.getSubscribeId()));
			// 房号
			Response<ProjectRoom> projectRoomResponse = projectRoomServiceFacade.findById(signed.getRoomId());
			if (projectRoomResponse.isSuccess() && null != projectRoomResponse.getEntity()) {
				data.put("roomName", projectRoomResponse.getEntity().getCombinedName());
			} else {
				data.put("roomName", "");
			}

			Response<User> userResponse = userServiceFacade.findById(signed.getAgentId());
			if (userResponse.isSuccess() && null != userResponse.getEntity()) {
				data.put("agentName", userResponse.getEntity().getUserName());
			} else {
				data.put("agentName", "");
			}
			data.put("remark", "");
			data.put("tcCreateTime", "");
			if (StringUtils.isNotBlank(businessAbnormaId)) {
				Response<BusinessAbnorma> businessAbnormaResponse = businessAbnormaServiceFacade
						.findById(Long.valueOf(businessAbnormaId));

				if (businessAbnormaResponse.isSuccess() && null != businessAbnormaResponse.getEntity()) {
					data.put("remark", businessAbnormaResponse.getEntity().getRemark());
					User actUser = userServiceFacade.findById(businessAbnormaResponse.getEntity().getCreateUserId())
							.getEntity();
					data.put("actCreateName", actUser.getUserName());
					data.put("tcCreateTime", DateUtils.DateToString(businessAbnormaResponse.getEntity().getCreateTime(),
							DateStyle.YYYY_MM_DD.getValue()));
				}
			}
		}
		return data;
	}

	public Double getSubscribeAmount(Long payDepositId, Long subscribeId) {
		HashMap<String, Double> maps = signedServiceFacade.signedContractAmount(payDepositId, subscribeId);
		Double payAepositAmount = 0d;
		if (null != maps.get("payAepositAmount")) {
			payAepositAmount = maps.get("payAepositAmount");
		}
		// 判断是否认购转签约，如果是则用已收认购金额-认筹转认购金额
		if (null != subscribeId) {
			Double subscribeAmount = 0d;
			if (null != maps.get("subscribeAmount")) {
				subscribeAmount = maps.get("subscribeAmount");
			}
			return subscribeAmount - payAepositAmount;
		} else {
			return 0d;
		}
	}

	/**
	 * 延期签约信息
	 * 
	 * @param subscribeId
	 *            签约Id
	 * @param businessAbnormaId
	 *            销控异常业务Id
	 * @return
	 */
	@Override
	public JSONObject loadSubDelaySigned(Long subscribeId, String businessAbnormaId) {
		JSONObject data = new JSONObject();
		Response<SubscribeInfo> response = subscribeServiceFacade.findByIdInfo(subscribeId);
		if (response.isSuccess() && null != response.getEntity()) {
			SubscribeInfo subscribe = response.getEntity();
			String subscribeStr = JSON.toJSONString(subscribe);
			data = JSONObject.parseObject(subscribeStr);
			Date conversionSignDate = subscribe.getConversionSignDate();
			if (null != conversionSignDate)
				data.put("conversionSignDate",
						com.emm.yixun.common.utils.DateUtils.DateToString(conversionSignDate, DateStyle.YYYY_MM_DD));
			// 客户名称
			Response<Customer> customerResponse = customerServiceFacade.findById(subscribe.getCustomerId());
			if (customerResponse.isSuccess() && null != customerResponse.getEntity()) {
				data.put("customerName", customerResponse.getEntity().getCustomerName());
			} else {
				data.put("customerName", "");
			}
			// 应收认购金
			data.put("needSubscribeAmount", subscribe.getDepositReceivable());
			data.put("depositReceivable", haveReceiveRefundServiceFacade.findSubscribeHaveAmount(subscribeId).getEntity());
			// 房号
			Response<ProjectRoom> projectRoomResponse = projectRoomServiceFacade.findById(subscribe.getRoomId());
			if (projectRoomResponse.isSuccess() && null != projectRoomResponse.getEntity()) {
				data.put("roomName", projectRoomResponse.getEntity().getCombinedName());
				String propertyType = projectRoomResponse.getEntity().getPropertyType();
				if (StringUtils.isNotBlank(propertyType)) {
					data.put("propertyTypeName", PropertyTypeEnum.getByNo(propertyType).getDes());
				} else {
					data.put("propertyTypeName", "");
				}

			} else {
				data.put("roomName", "");
				data.put("propertyTypeName", "");
			}
			data.put("agentName", subscribe.getUserName());
			data.put("remark", "");
			if (StringUtils.isNotBlank(businessAbnormaId)) {
				Response<BusinessAbnorma> businessAbnormaResponse = businessAbnormaServiceFacade
						.findById(Long.valueOf(businessAbnormaId));
				data.put("tcCreateTime", "");
				data.put("delayDate", "");
				if (businessAbnormaResponse.isSuccess() && null != businessAbnormaResponse.getEntity()) {
					if (null != businessAbnormaResponse.getEntity().getConversionSignDate()
							&& null != businessAbnormaResponse.getEntity().getDelaydate()) {
						long subDay = com.emm.yixun.common.utils.DateUtils.getDaysSub(
								businessAbnormaResponse.getEntity().getConversionSignDate(),
								businessAbnormaResponse.getEntity().getDelaydate());
						data.put("delayShowDay", subDay + "天");
					}

					data.put("remark", businessAbnormaResponse.getEntity().getRemark());
					data.put("tcCreateTime", DateUtils.formatDate(businessAbnormaResponse.getEntity().getCreateTime(),
							DateStyle.YYYY_MM_DD.getValue()));
					if (null != businessAbnormaResponse.getEntity().getDelaydate())
						data.put("delayDate", DateUtils.formatDate(businessAbnormaResponse.getEntity().getDelaydate(),
								DateStyle.YYYY_MM_DD.getValue()));
				}
			}
		}
		return data;
	}

	/**
	 * 签约折扣、签约审核信息
	 */
	@Override
	public Map<String, Object> loadSignedInfo(Long signedId) {
		Map<String, Object> map = new HashMap<String, Object>();
		Response<SignedInfo> signedRes = signedServiceFacade.findByIdInfo(signedId);
		if (signedRes.isSuccess()) {
			SignedInfo signed = signedRes.getEntity();
			User createUser = userServiceFacade.findById(signed.getCreateUserId()).getEntity();
			signed.setCreateNameStr(createUser.getUserName());
			signed.getCreateUserId();
			JSONArray dtArray = new JSONArray();
			// 证件类型 BaseCodeTypeEnum
			// 支付方式 PaymentMethodEnum
			// 合同类型 ContactTypeEnum

			String shouStatus = "0";
			// 收款按钮 已收金额 等于合同金额。不显示
			// 已收金额
			HaveReceiveRefundDto hrrDto = new HaveReceiveRefundDto();
			hrrDto.setRelationId(signed.getId());
			hrrDto.setDocType(DocTypeEnum.COLLECTION.getNo());
			hrrDto.setReceivablesType(ReceivablesTypeEnum.SIGNED.getNo());
			hrrDto.setTransferStatus("0");
			double haveCollection = haveReceiveRefundService.getRealAmount(hrrDto);
			if (new BigDecimal(haveCollection).compareTo(signed.getSignAmount()) == 0) {
				shouStatus = "1";
			}
			map.put("shouStatus", shouStatus);
			map.put("procInstId", signed.getProcInstId());
			NeedReceiveRefundDto needReceiveRefundDto = new NeedReceiveRefundDto();
			needReceiveRefundDto.setBusinessType("2");// 签约
			needReceiveRefundDto.setRelationId(signed.getId());
			map.put("auditStatus", signed.getAuditStatus());
			map.put("businessStatus", signed.getBusinessStatus());
			if (signed.getBusinessStatus().equals("2")) {
				BusinessAbnormaDto businessAbnormaDto = new BusinessAbnormaDto();
				businessAbnormaDto.setBusinessId(signed.getId());
				businessAbnormaDto.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_4.getNo());
				businessAbnormaDto.setAuditStatus(AuditStatusEnum.SUCCESS.getNo());
				ResponseList<BusinessAbnorma> businessAbnormas = businessAbnormaServiceFacade
						.findByDto(businessAbnormaDto);
				if (businessAbnormas.isSuccess() && businessAbnormas.getEntity() != null
						&& businessAbnormas.getEntity().size() != 0) {
					map.put("businessAbnormaId", businessAbnormas.getEntity().get(0).getId());
					map.put("huanStatus", "1");
				} else {
					map.put("huanStatus", "0");
				}
			} else if (!signed.getBusinessStatus().equals("3")) {
				BusinessAbnormaDto businessAbnormaDto = new BusinessAbnormaDto();
				businessAbnormaDto.setBusinessId(signed.getId());
				businessAbnormaDto.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_3.getNo());
				// businessAbnormaDto.setAuditStatus(AuditStatusEnum.AUDIT.getNo());
				ResponseList<BusinessAbnorma> businessAbnormas = businessAbnormaServiceFacade
						.findByDto(businessAbnormaDto);
				if (businessAbnormas.isSuccess() && businessAbnormas.getEntity() != null
						&& businessAbnormas.getEntity().size() != 0) {
					BusinessAbnorma abnorma = businessAbnormas.getEntity().get(0);
					if (abnorma.getAuditStatus().equals("1")) {// 待提交隐藏
						map.put("huanStatus", "1");
					} else if (abnorma.getAuditStatus().equals("2")) {// 已退回显示
						map.put("huanStatus", "0");
					}
				} else {
					map.put("huanStatus", "0");
				}
			} else {// 已通过隐藏
				BusinessAbnormaDto businessAbnormaDto = new BusinessAbnormaDto();
				businessAbnormaDto.setBusinessId(signed.getId());
				businessAbnormaDto.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_3.getNo());
				businessAbnormaDto.setAuditStatus(AuditStatusEnum.SUCCESS.getNo());
				ResponseList<BusinessAbnorma> businessAbnormas = businessAbnormaServiceFacade
						.findByDto(businessAbnormaDto);
				if (businessAbnormas.isSuccess() && businessAbnormas.getEntity() != null
						&& businessAbnormas.getEntity().size() != 0) {
					map.put("businessAbnormaId", businessAbnormas.getEntity().get(0).getId());
					map.put("huanStatus", "1");
				} else {
					map.put("huanStatus", "0");
				}
			}
			if (signed.getDiscountAfterPrice() == null) {
				signed.setDiscountAfterPrice(new BigDecimal("0"));
			}
			String subscribeStr = JSON.toJSONString(signed);
			JSONObject signedRecordJson = JSONObject.parseObject(subscribeStr);
			signedRecordJson.put("contactTypeName",
					StringUtils.isNotBlank(signed.getContactType())
							? ContactTypeEnum.getByNo(signed.getContactType()).getDes()
							: "");
			signedRecordJson.put("paymentMethodName",
					StringUtils.isNotBlank(signed.getPaymentMethod())
							? PaymentMethodEnum.getByNo(signed.getPaymentMethod()).getDes()
							: "");
			signedRecordJson.put("dealCategoryName",
					StringUtils.isNotBlank(signed.getDealCategory())
							? DealCategoryEnum.getByNo(signed.getDealCategory()).getDes()
							: "");
			HashMap<String, Double> maps = signedServiceFacade.signedContractAmount(signed.getPayDepositId(),
					signed.getSubscribeId());
			Double payAepositAmount = maps.get("payAepositAmount");
			signedRecordJson.put("payAepositAmount", payAepositAmount);
			// 判断是否认购转签约，如果是则用已收认购金额-认筹转认购金额
			if (null != signed.getSubscribeId()) {
				signedRecordJson.put("subscribeAmount", maps.get("subscribeAmount") - payAepositAmount);
			} else {
				signedRecordJson.put("subscribeAmount", "0");
			}

			map.put("signedRecord", signedRecordJson);
			JSONObject estateRecord = getEstateRecord(signed.getRoomId());
			estateRecord.put("calculateArea", signed.getCalculateArea());
			estateRecord.put("unitPrice", signed.getConversionPrice());
			estateRecord.put("totalPrice", signed.getLumpsumPrice());
			map.put("estateRecord", estateRecord);

			// 已退金额
			hrrDto.setRelationId(signed.getId());
			hrrDto.setDocType(DocTypeEnum.REFUND.getNo());
			hrrDto.setReceivablesType(ReceivablesTypeEnum.SIGNED.getNo());
			double haveRefund = haveReceiveRefundService.getRealAmount(hrrDto);
			// 是否可变更合同 false:不隐藏, true: 隐藏按钮
			boolean contactChange = true;
			if (haveCollection - haveRefund == 0) {
				contactChange = false;
			}
			map.put("contactChangeFlag", contactChange);

			JSONObject customerRecord = getCustomerRecord(signed.getCustomerId());
			map.put("customerRecord", customerRecord);
			map.put("userName", signed.getUserName());
			map.put("documentType", dtArray);
			map.put("signedId", signedId);
		}
		return map;
	}

	@Override
	public SignedChangeVo loadSignedChangeRoomInfo(Long signedId) {
		SignedChangeVo signedChangeVo = null;
		if (null != signedId) {
			// 签约信息
			SignedDto signedDto = new SignedDto();
			signedDto.setId(signedId);
			Response<SignedDto> resSignedDto = signedServiceFacade.selectChangeSignedByDto(signedDto);
			signedDto = resSignedDto.getEntity();
			if (signedDto != null) {
				signedChangeVo = new SignedChangeVo();
				BusinessAbnormaDto baDto = new BusinessAbnormaDto();
				baDto.setBusinessId(signedDto.getId());
				baDto.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_3.getNo());
				ResponseList<BusinessAbnorma> resBaList = businessAbnormaServiceFacade.findByDto(baDto);
				if (null != resBaList) {
					List<BusinessAbnorma> baList = resBaList.getEntity();
					if (null != baList) {
						for (BusinessAbnorma ba : baList) {
							ProjectRoom pr = new ProjectRoom();
							if (null != ba.getNewRoomId()) {
								Response<ProjectRoom> resPr = projectRoomServiceFacade.findById(ba.getNewRoomId());
								if (resPr.isSuccess()) {
									pr = resPr.getEntity();
								}
							}
							Response<User> resUser = userServiceFacade.findById(ba.getCreateUserId());
							User user = new User();
							if (resUser.isSuccess()) {
								user = resUser.getEntity();
							}
							// if (AuditStatusEnum.TOSUBMIT.getNo().equals( ba.getAuditStatus())||
							// AuditStatusEnum.AUDIT.getNo().equals(ba.getAuditStatus())) {
							signedChangeVo.setNew_roomName(pr.getCombinedName());
							signedChangeVo.setCalculateArea(ba.getCalculateArea());
							signedChangeVo.setBfdUnitPrice(ba.getBfdUnitPrice());
							signedChangeVo.setBfdTotalPrice(ba.getBfdTotalPrice());
							signedChangeVo.setRemark(ba.getRemark());
							signedChangeVo.setApplyDate(ba.getCreateTime());
							signedChangeVo.setApplyDateStr(DateUtils.DateToString(ba.getCreateTime(),
									DateStyle.YYYY_MM_DD_HH_MM_SS_EN.getValue()));
							signedChangeVo.setAgentName(user.getUserName());
							// }
						}
					}
				}

				signedChangeVo.setOld_signCode(signedDto.getSignCode());
				signedChangeVo.setOld_businessType("签约");
				signedChangeVo.setOld_customerName(signedDto.getCustomerName());
				signedChangeVo.setOld_hrrReceived(hrrReceived(signedDto.getId()).toString());
				signedChangeVo.setOld_didTime(signedDto.getDidTime());
				signedChangeVo.setOld_didTimeStr(
						DateUtils.DateToString(signedDto.getDidTime(), DateStyle.YYYY_MM_DD_EN.getValue()));
				signedChangeVo.setOld_roomName(signedDto.getRoomName());
				signedChangeVo.setOld_calculateArea(signedDto.getCalculateArea());
				signedChangeVo.setOld_conversionPrice(signedDto.getSignPrice());
				signedChangeVo.setOld_lumpsumPrice(signedDto.getLumpsumPrice());
			} else {
				return signedChangeVo;
			}
		}
		return signedChangeVo;
	}

	private BigDecimal hrrReceived(Long signedId) {
		BigDecimal realAmount = new BigDecimal("0");
		HaveReceiveRefundDto dto = new HaveReceiveRefundDto();
		dto.setRelationId(signedId);
		dto.setReceivablesType("2");
		dto.setDocType(DocTypeEnum.COLLECTION.getNo());
		ResponseList<HaveReceiveRefund> havResponseList = haveReceiveRefundServiceFacade.findByDto(dto);
		if (!havResponseList.isSuccess()) {
			return realAmount;
		}
		if (havResponseList.getEntity() == null) {
			return realAmount;
		}
		for (HaveReceiveRefund hrr : havResponseList.getEntity()) {
			realAmount = realAmount.add(hrr.getRealAmount());
		}
		return realAmount;
	}

	@Override
	public JSONObject loadDeferredPaymentDetail(Long businessAbnormaId) {
		JSONObject data = new JSONObject();
		Response<BusinessAbnorma> baResponse = businessAbnormaServiceFacade.findById(businessAbnormaId);
		BusinessAbnorma businessAbnorma = baResponse.getEntity();
		Long businessId = businessAbnorma.getBusinessId();
		User acrUserName = userServiceFacade.findById(businessAbnorma.getCreateUserId()).getEntity();
		data.put("acrUserName", acrUserName.getUserName());

		data.put("createTime", com.emm.yixun.common.utils.DateUtils.DateToString(businessAbnorma.getCreateTime(),
				DateStyle.YYYY_MM_DD));
		data.put("remark", businessAbnorma.getRemark());
		if (null != businessAbnorma.getConversionSignDate()) {
			data.put("receivablesDate", com.emm.yixun.common.utils.DateUtils
					.DateToString(businessAbnorma.getConversionSignDate(), DateStyle.YYYY_MM_DD));

			Date delayStartDay = com.emm.yixun.common.utils.DateUtils.addDay(businessAbnorma.getConversionSignDate(),
					1);
			data.put("delayStartDay",
					com.emm.yixun.common.utils.DateUtils.DateToString(delayStartDay, DateStyle.YYYY_MM_DD));

			// 延期天数-应收日期
			Long cuurDelayDayCount = com.emm.yixun.common.utils.DateUtils
					.getDaysSub(businessAbnorma.getConversionSignDate(), businessAbnorma.getDelaydate());
			data.put("cuurDelayDayCount", cuurDelayDayCount);
		} else {
			// 应收日期
			data.put("receivablesDate", "");
			// 延期开始日期
			data.put("delayStartDay", "");

			// 延期天数
			data.put("cuurDelayDayCount", "0");
		}
		// 查询应收款
		Response<NeedReceiveRefund> nrrResopnse = needReceiveRefundServiceFacade.findById(businessId);

		// 查询签约
		NeedReceiveRefund needReceiveRefund = nrrResopnse.getEntity();
		if (null != needReceiveRefund) {
			// 应收款项
			data.put("receivablesFunds", needReceiveRefund.getReceivablesFunds());
			// 应收金额
			data.put("totalReceivablesAmount", needReceiveRefund.getTotalReceivablesAmount());

			Response<BigDecimal> res = haveReceiveRefundServiceFacade.findHaveAmount(needReceiveRefund.getId());
			if (res.isSuccess()) {
				data.put("haveReceivedTotal", res.getEntity());
			} else {
				// 已收金额(元)
				data.put("haveReceivedTotal", "");
			}

			// 延期结束日期
			data.put("delayEndDay", com.emm.yixun.common.utils.DateUtils.DateToString(businessAbnorma.getDelaydate(),
					DateStyle.YYYY_MM_DD));

			// 已延期天数
			BusinessAbnormaDto queryDto = new BusinessAbnormaDto();
			queryDto.setBusinessId(businessAbnorma.getBusinessId());
			queryDto.setBusinessType(BusinessAbnormaEnum.BusinessAbnorma_12.getNo());
			queryDto.setAuditStatus(AuditStatusEnum.SUCCESS.getNo());
			queryDto.setOrders(" t.id asc ");
			ResponseList<BusinessAbnorma> responseList = businessAbnormaServiceFacade.findByDto(queryDto);
			if (responseList.isSuccess() && null != responseList.getEntity() && responseList.getEntity().size() > 0) {
				BusinessAbnorma first = responseList.getEntity().get(0);
				Long delayDayCount = com.emm.yixun.common.utils.DateUtils.getDaysSub(first.getConversionSignDate(),
						needReceiveRefund.getReceivablesDate());
				data.put("delayDayCount", delayDayCount);

			} else {
				// 已延期天数
				data.put("delayDayCount", "0");

			}
		}
		Long signedId = needReceiveRefund.getRelationId();
		Response<SignedInfo> signedResponse = signedServiceFacade.findByIdInfo(signedId);
		if (signedResponse.isSuccess() && null != signedResponse.getEntity()) {
			SignedInfo signed = signedResponse.getEntity();
			// 计价面积
			data.put("calculateArea", signed.getCalculateArea());
			data.put("signPrice", signed.getSignPrice());
			data.put("signAmount", signed.getSignAmount());
			data.put("signedId", signed.getId());
			data.put("userName", signed.getUserName());

			// 客户名称
			Response<Customer> customerResponse = customerServiceFacade.findById(signed.getCustomerId());
			if (customerResponse.isSuccess() && null != customerResponse.getEntity()) {
				data.put("customerName", customerResponse.getEntity().getCustomerName());
			} else {
				data.put("customerName", "");
			}

			// 房号
			Response<ProjectRoom> projectRoomResponse = projectRoomServiceFacade.findById(signed.getRoomId());
			if (projectRoomResponse.isSuccess() && null != projectRoomResponse.getEntity()) {
				data.put("roomName", projectRoomResponse.getEntity().getCombinedName());
				PropertyTypeEnum enumOject = PropertyTypeEnum
						.getByNo(projectRoomResponse.getEntity().getPropertyType());
				data.put("propertyTypeName", enumOject == null ? "" : enumOject.getDes());
			} else {
				data.put("roomName", "");
				data.put("propertyTypeName", "");
			}

			// 付款方式
			PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.getByNo(signed.getPaymentMethod());
			if (null != paymentMethodEnum) {
				data.put("paymentMethodName", paymentMethodEnum.getDes());
			} else {
				data.put("paymentMethodName", "");
			}
		}
		return data;
	}

	@Override
	public AjaxRes processCheck(String taskId, String checkStatus, String message, Long userId) throws Exception {
		AjaxRes ar = new AjaxRes();
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		if (null == task) {
			ar.setFailMsg("审核失败：当前任务不存在！");
			return ar;
		}
		Object objectId = runtimeService.getVariable(task.getExecutionId(), "processProjectId");
		if (null == objectId) {
			ar.setFailMsg("审核失败：流程参数错误！");
			return ar;
		}
		Long processProjectId = (Long) objectId;
		User user = userServiceFacade.findById(userId).getEntity();
		// 保存流程全局变量
		Map<String, Object> globalVariables = new HashMap<String, Object>();
		globalVariables.put("processCheckStatus", checkStatus);
		// 下一步处理人初始化为空
		globalVariables.put("nextUserId", "");
		String nextNodeId = activitiProcessServiceImpl.getNextNodeId(task.getProcessInstanceId());
		List<String> userIdList = new ArrayList<String>();
		if (null != nextNodeId) {
			userIdList = activitiProcessServiceImpl.getNodeUserId(user.getMerchantId(), processProjectId,
					/* task.getProcessDefinitionId() */null, nextNodeId);
			if (userIdList.size() > 0) {
				globalVariables.put("nextUserId", userIdList.get(0));
			} else {
				ar.setFailMsg("下一个节点处理人未设置");
				return ar;
			}
		}

		runtimeService.setVariables(task.getExecutionId(), globalVariables);
		identityService.setAuthenticatedUserId(user.getUserAccount());
		// 保存审批人以及审批意见
		taskService.addComment(taskId, task.getProcessInstanceId(), message);
		// 保存节点审核状态
		taskService.setVariableLocal(task.getId(), "taskCheckStatus", checkStatus);
		// 业务ID
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
				.processInstanceId(task.getProcessInstanceId()).singleResult();
		// checkStatus 0通过 1不通过
		if (checkStatus.equals("0")) {
			// 审批完成，设置
			taskService.complete(task.getId());

			if(pmoConfig.isSendOaMsg()){
				// 发送已办
				oaSendHttpMessageService.sendHaveMessage(task, processInstance, user, ActRemarkEnum.ACT_2,
						processInstance.getProcessDefinitionName());
				TaskQuery taskQuery = taskService.createTaskQuery().taskDefinitionKey(nextNodeId)
						.executionId(task.getExecutionId());
				List<Task> queryTaskList = taskQuery.list();
				if (queryTaskList != null && queryTaskList.size() > 0) {
					Long userNextId = globalVariables.get("nextUserId") == null ? null
							: new Long(globalVariables.get("nextUserId").toString());
					// 发送待办
					oaSendHttpMessageService.sendWaitMessage(task, processInstance, user, userNextId,
							queryTaskList.get(0).getId(), processInstance.getProcessDefinitionName());
				} else {
					// 发送办结
					oaSendHttpMessageService.sendHaveMessage(task, processInstance, user, ActRemarkEnum.ACT_4,
							processInstance.getProcessDefinitionName());
				}
			}

		} else if (checkStatus.equals("1")) {
			// 终止流程
			activitiProcessServiceImpl.endProcess(task.getId(), null);
			// 审核不通过，办结
			if(pmoConfig.isSendOaMsg()) {
				oaSendHttpMessageService.sendHaveMessage(task, processInstance, user, ActRemarkEnum.ACT_4,
						processInstance.getProcessDefinitionName());
			}
		}
		if (StringUtils.isNotBlank(nextNodeId))
			sendMessageServiceFacade.applyMessageSend(task.getProcessInstanceId(), nextNodeId, userIdList);
		// 更新审核时间到业务表
		processService.updateBusinessCheckDate(task.getProcessInstanceId());
		ar.setSucceed("操作成功");
		return ar;

	}

	@Override
	public String getWorkFlowName(String processId) {
		try {
			ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processId)
					.singleResult();
			if (!StringUtils.isEmpty(processInstance.getProcessDefinitionName())) {
				return processInstance.getProcessDefinitionName();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public HashMap<String, String> getOaId(String userId, String userticket) {
		HashMap<String, String> map = new HashMap<String, String>();
		logger.info("*************start request**************");
		logger.info("userid=" + userId);
		String cacheKey = String.format(EhcacheConstant.OA_USER_KEY, userId);
		Object userCache = cacheUtils.get(EhcacheConstant.ACTIVE_SESSIONS_CACHE, cacheKey);
		logger.info("*************vaild cache user:" + userCache + "**************");
		if (userCache == null) {
			try {
				map = getUser(userticket);
			} catch (Exception e) {
				map.put("error", "请退出重新进入!");
				e.printStackTrace();
			}
		} else {
			User user = (User) userCache;
			map.put("oaId", user.getOaUserCode());
		}
		logger.info("********获取用户方法返回数据:" + map + "********");
		return map;
	}

	@Override
	public HashMap<String, String> getUser(String userticket) {
		HashMap<String, String> map = new HashMap<String, String>();
		if (StringUtils.isEmpty(userticket)) {
			map.put("error", "userticket为空!");
			return map;
		}
		Map<String, String> params = new HashMap<String, String>();
		params.put("ticket", userticket);
		logger.info("*****************" + "request url: " + pmoConfig.getOaBridgeUrl() + "************************");
		logger.info("*****************request params:" + params + "*******************");
		String json = HttpUtil.doPost(pmoConfig.getOaBridgeUrl(), params, "utf-8");
		logger.info("*******************request result:" + json + "***************");
		if (!StringUtils.isEmpty(json)) {
			BridgeResult bridgeResult = JSONObject.parseObject(json, BridgeResult.class);
			if (bridgeResult.getErrcode().equals("0")) { // 正常
				String userAccount = bridgeResult.getWxuserkey();
				UserDto userdto = new UserDto();
				userdto.setUserAccount(userAccount);
				userdto.setDelFlag(DelFlagEnum.UNDEL.getNo());
				ResponseList<User> responseList = userServiceFacade.findByDto(userdto);
				if (responseList.isSuccess() && responseList.getEntity() != null
						&& responseList.getEntity().size() > 0) {
					User user = responseList.getEntity().get(0);
					logger.info("map put oaUserCode:" + user.getOaUserCode());
					String cacheKey = String.format(EhcacheConstant.OA_USER_KEY, user.getOaUserCode());
					cacheUtils.put(EhcacheConstant.ACTIVE_SESSIONS_CACHE, cacheKey, user);
					map.put("oaId", user.getOaUserCode());
				} else {
					map.put("error", "用户:" + userAccount + "不存在!");
				}
			} else {
				map.put("error", bridgeResult.getErrmsg());
			}
		} else {
			map.put("error", "接口返回信息为空!");
		}
		return map;
	}
}
